﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Data;
using Entities;

namespace Logic
{
    public sealed class VotingLogic
    {
        public string InsertVoting(Voting voting, List<Candidate> candidateList, List<Group> groups, string key)
        {
            List<Candidate> validList = new List<Candidate>();
            string message = null;
            foreach (Candidate c in candidateList)
            {

                c.name = c.name.CleanParameter<string>().FirstToUpper();
                c.middleName = c.middleName.CleanParameter<string>();
                c.lastName = c.lastName.CleanParameter<string>().FirstToUpper();
                c.secondLastName = c.secondLastName.CleanParameter<string>().FirstToUpper();
                c.office = c.office.CleanParameter<string>().FirstToUpper();
                c.nameSQLTable = c.nameSQLTable.RemoveWhitespace();
                c.pictureString = c.pictureString.CleanParameter<string>();
                c.nameSQLProcedure = c.nameSQLProcedure.CleanParameter<string>().RemoveWhitespace();
                c.email = c.email.CleanParameter<string>();
                c.telephone = c.telephone.CleanParameter<string>();
                c.cellPhone = c.cellPhone.CleanParameter<string>();
            }

            voting.name = voting.name.CleanParameter<string>();
            voting.votingDateStart = voting.votingDateStart.CleanParameter<DateTime>();
            voting.votingDateEnd = voting.votingDateEnd.CleanParameter<DateTime>();
            voting.votingStartTime = voting.votingStartTime.CleanParameter<string>();
            voting.votingEndTime = voting.votingEndTime.CleanParameter<string>();

            foreach (Candidate candidate in candidateList)
            {
                if (candidate.name.ValidateText(30))
                {
                    if (candidate.lastName.ValidateText(30))
                    {
                        if (candidate.secondLastName.ValidateText(30))
                        {
                            if (candidate.picture.ValidatePicture())
                            {
                                if (candidate.office.ValidateText(30))
                                {
                                    if (candidate.nameSQLProcedure.ValidateText(150))
                                    {
                                        if (candidate.middleName.ValidateText(30))
                                        {
                                            if (candidate.email.ValidateMail(50))
                                            {
                                                if (candidate.telephone.ValidateTelephone(9))
                                                {
                                                    if (candidate.cellPhone.ValidateTelephone(9))
                                                    {
                                                        if (candidate.nameSQLTable.ValidateText(150))
                                                        {
                                                            validList.Add(candidate);
                                                        }
                                                        else
                                                        {
                                                            validList = null;
                                                            message = "Error: Campo Invalido ";
                                                            break;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        validList = null;
                                                        message = "Error: Celular Invalido ";
                                                        break;
                                                    }
                                                }
                                                else
                                                {
                                                    validList = null;
                                                    message = "Error: Telefono Invalido ";
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                validList = null;
                                                message = "Error: Email Invalido ";
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            validList = null;
                                            message = "Error: Segundo Nombre Invalido ";
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        validList = null;
                                        message = "Error: Campo Invalido ";
                                        break;
                                    }
                                }
                                else
                                {
                                    validList = null;
                                    message = "Error: Cargo Invalido ";
                                    break;
                                }

                            }
                            else
                            {
                                validList = null;
                                message = "Error: Imagen Invalida. ";
                                break;
                            }
                        }
                        else
                        {
                            validList = null;
                            message = "Error: Apellido Invalido ";
                            break;
                        }
                    }
                    else
                    {
                        validList = null;
                        message = "Error: Segundo Apellido Invalido ";
                        break;
                    }
                }
                else
                {
                    validList = null;
                    message = "Error: Nombre Invalido ";
                    break;
                }

            }

            bool validateGroup = false;
            foreach (Group g in groups)
            {

                g.id = g.id.CleanParameter<string>();

                if (g.id.IsNumber())
                {
                    validateGroup = true;
                }
                else
                {
                    validateGroup = false;
                    break;
                }
            }

            if (validateGroup && validList != null && voting.name.ValidateText(100) && voting.votingDateStart.ValidateDate()
                && voting.votingDateEnd.ValidateDate() && voting.votingStartTime.ValidateHour() && voting.votingEndTime.ValidateHour())
            {
                VotingData cd = new VotingData();
                bool response = cd.InsertVoting(voting, validList, groups);
                if (response)
                {
                    message = "ingresado";
                }
                else
                {
                    message = "noIngresado";
                }
            }
            else
            {
                return message;
            }
            return message;

        }

        public List<Candidate> GetListCandidatesLogic(string key, string votingId)
        {
            votingId = Encryption.DecryptData(votingId, key);

            if (votingId != null && votingId.IsNumber())
            {
                VotingData cd = new VotingData();

                List<Candidate> bdList = cd.GetListCandidates(Convert.ToInt32(votingId));
                if (bdList != null)
                {

                    Parallel.ForEach(bdList, cc =>
                     {

                         cc.id = Encryption.EncriptData(cc.id.ToString(), key);
                     }
                  );


                    return bdList;
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        public Candidate GetCandidateByIdLogic(string id, string key, bool flag)
        {
            //if flag is true, the id is Decrypt
            if (!flag)
            {
                id = Encryption.DecryptData(id, key);
            }
            id = id.CleanParameter<string>();
            VotingData cd = new VotingData();

            if (id.IsNumber())
            {
                return cd.GetCandidateById(id);
            }
            else
            {
                return null;
            }
        }

        public Dictionary<string, string> DecryptDictionaryLogic(Dictionary<string, string> ids, string key)
        {
            Dictionary<string, string> decryptDic = new Dictionary<string, string>();
            foreach (KeyValuePair<string, string> id in ids)
            {
                if (!string.IsNullOrWhiteSpace(id.Value) && !string.IsNullOrWhiteSpace(id.Key))
                {
                    decryptDic.Add(id.Key.Replace("GrupoRadio", ""), Encryption.DecryptData(id.Value.CleanParameter<string>(), key));
                }
                else
                {
                    decryptDic = null;
                    break;
                }
            }

            return decryptDic;
        }

        public bool InsertarCandidatoLogica(List<Candidate> candidateList, Voter i)
        {
            bool response = false;
            VotingData votingData = new VotingData();

            if (votingData.InsertCandidate(candidateList, i))
            {
                response = true;
            }

            return response;
        }

        public List<string> GetListCandidatesOfficesLogic()
        {
            return new VotingData().GetListCandidatesOffices();
        }

        public bool UpdateCandidateLogic(Candidate candidate, string oldTableName, string oldProcedureName)
        {
            candidate.name = candidate.name.CleanParameter<string>().FirstToUpper();
            candidate.middleName = candidate.middleName.CleanParameter<string>();
            candidate.lastName = candidate.lastName.CleanParameter<string>().FirstToUpper();
            candidate.secondLastName = candidate.secondLastName.CleanParameter<string>().FirstToUpper();
            candidate.office = candidate.office.CleanParameter<string>().FirstToUpper();
            candidate.email = candidate.email.CleanParameter<string>();
            candidate.telephone = candidate.telephone.CleanParameter<string>();
            candidate.cellPhone = candidate.cellPhone.CleanParameter<string>();
            candidate.nameSQLTable = "Tbl_Candidato_" + candidate.office + "_" + candidate.name + "_" + candidate.lastName;
            candidate.nameSQLProcedure = "InsertarCandidato_" + candidate.office + "_" + candidate.name + "_" + candidate.lastName;
            candidate.nameSQLTable = candidate.nameSQLTable.RemoveWhitespace();
            candidate.nameSQLProcedure = candidate.nameSQLProcedure.RemoveWhitespace();
            candidate.pictureString = candidate.pictureString.CleanParameter<string>();

            if (candidate.name.ValidateText(30) && candidate.middleName.ValidateText(30) && candidate.lastName.ValidateText(30) &&
                candidate.secondLastName.ValidateText(30) && candidate.office.ValidateText(30) && candidate.email.ValidateMail(50) &&
                candidate.telephone.ValidateTelephone(9) && candidate.cellPhone.ValidateTelephone(9) && candidate.pictureString.Length <= 70)
            {
                return new VotingData().UpdateCandidate(candidate, oldTableName, oldProcedureName);
            }
            else
            {
                return false;
            }
        }

        public bool DeleteCandidateLogic(Candidate candidate)
        {
            return new VotingData().DeleteCandidate(candidate);
        }

        public string EncryptLogic(string data, string key)
        {
            return Encryption.EncriptData(data, key);
        }

        public string DecryptLogic(string data, string key)
        {
            return Encryption.DecryptData(data, key);
        }

        public List<Voting> GetListVotingLogic(string key)
        {
            List<Voting> list = new VotingData().GetListVoting();

            if (list != null)
            {

                //por cada votacion que NO este bloqueada
                foreach (Voting v in list.Where(x => x.votingBlocked == false))
                {
                    v.id = EncryptLogic(v.id, key);
                    v.votingDateStart = v.votingDateStart.Date;
                    v.votingDateEnd = v.votingDateEnd.Date;

                    if (v.groups != null)
                    {
                        foreach (Group g in v.groups)
                        {
                            v.groupsView += g.name + "</br>";
                        }
                    }
                    else
                    {
                        v.groupsView = "No existen grupos";
                    }

                }

                return list;
            }
            else
            {
                return null;
            }

        }

        public List<Voting> GetListVotingOfVotersLogic(string key, string voterId)
        {
            List<Voting> list = new VotingData().GetListActiveVotingByVoterId(Convert.ToInt32(voterId));

            if (list != null)
            {
                foreach (Voting v in list)
                {
                    v.id = EncryptLogic(v.id, key);
                    v.votingDateStart = v.votingDateStart.Date;
                    v.votingDateEnd = v.votingDateEnd.Date;
                }

                return list;
            }
            else
            {
                return null;
            }

        }

        public List<Voting> GetListVotingByVoterIdLogic(string key, string voterId)
        {
            List<Voting> list = new VotingData().GetListNoBlockedVotingByVoterId(Convert.ToInt32(voterId));

            if (list != null)
            {
                foreach (Voting v in list)
                {
                    v.id = EncryptLogic(v.id, key);
                    v.votingDateStart = v.votingDateStart.Date;
                    v.votingDateEnd = v.votingDateEnd.Date;
                }

                return list;
            }
            else
            {
                return null;
            }

        }

        public Voting GetVotingByIdList(string key, string id)
        {
            string dc = Encryption.DecryptData(id, key);

            if (dc != null && dc.IsNumber())
            {
                Voting v = new VotingData().GetVotingById(Convert.ToInt32(dc));

                if (v != null)
                {
                    return v;
                }
                else
                {
                    return null;
                }

            }
            else
            {
                return null;
            }
        }

        public List<VoucherVoting> GetListVoucherVotingLogic(string id, string key)
        {
            List<VoucherVoting> list = new VotingData().GetListVoucherVoting(id);

            if (list != null)
            {
                foreach (VoucherVoting c in list)
                {
                    c.votingId = EncryptLogic(c.votingId, key);
                }
                return list;
            }
            else
            {
                return null;
            }
        }
    }
}
